import Component from "../Component.js";
import Type from "../../experience/db/Type.js";
import { SensorClass, SensorType, SensorStatus } from "../../experience/drawer/SensorType.js";
import { URL } from "../../configure/Assets.js";
import Socket from "../../experience/utils/Socket.js";

export default class Sensor extends Component {
    constructor() {
        super();

        // 目的是为了显示sensor详情时,提前布局好屏幕右侧的位置
        const wh = this.utils.screen()
        const width = 480, height = wh.height / 4;
        for (let i = 0; i < 8; i++) {
            const j = i / 4 + 1;
            this.pins.push({
                x: wh.width - width * j,
                y: height * i,
                id: `p${this.utils.uuid()}`,
                popupId: ""
            });
        }
    }

    async refresh(data=null) {
        const config = this.algo.getConfig();
        if (config == null) return;

        let tree, sensors = [];
        if (data === null) {
            const data = await this.api.getSensorTree(config.mine_code);
            tree = data.data;
            console.log("tree => ", tree);
        } else {
            tree = data;
        }

        if (tree.children === null) return;
        for (const t0 of tree.children) {
            if (t0.children === null) continue;
            for (const t1 of t0.children) {
                if (t1.children === null) continue;
                for (const t2 of t1.children) {
                    sensors.push(t2);
                }
            }
        }

        await this.db.refresh(Type.Sensor, sensors);
        await this.drawer.draw(Type.Sensor);
    }

    async tree() {
        const config = this.algo.getConfig();
        if (config === null) {
            this.toast('请优先选择煤矿。');
            return;
        }

        this.$$("#pannel .page-content").empty()
        const div = `
            <div class="block block-strong no-padding-horizontal">
                <div class="treeview"></div>
            </div>
        `;
        this.$$("#pannel .page-content").append(div);

        let tree = this.utils.getLocalStorage("sensor");
        if (tree === null) {
            const data = await this.api.getSensorTree(config.mine_code);
            tree = data.data;
        }

        if (tree.children === null) return;
        for (const t0 of tree.children) {
            // 加入第一级别目录
            const td1Id = `t0${this.utils.uuid()}`, td1Div = `
                <div class="treeview-item treeview-item-opened" id="${td1Id}">
                    <div class="treeview-item-root">
                        <div class="treeview-toggle"></div>
                        <div class="treeview-item-content">
                            <i class="icon iconfont" style="color: ${SensorStatus[t0.sensorStatus]};">
                                ${SensorClass[t0.disasterType]}
                            </i>
                            <div class="treeview-item-label">${t0.label}</div>
                        </div>
                    </div>
                    <div class="treeview-item-children"></div>
                </div>
            `
            this.$$(`.treeview`).append(td1Div)

            if (t0.children === null) continue
            for (const t1 of t0.children) {
                // 加入第二级目录
                const td2Id = `t1${this.utils.uuid()}`, td2Div = `
                    <div class="treeview-item treeview-item-opened" id="${td2Id}">
                        <div class="treeview-item-root">
                            <div class="treeview-toggle"></div>
                            <div class="treeview-item-content">
                                <i class="icon iconfont" style="color: ${SensorStatus[t1.sensorStatus]};">
                                    ${SensorClass[t1.disasterType]}
                                </i>
                                <div class="treeview-item-label">${t1.label}</div>
                            </div>
                        </div>
                        <div class="treeview-item-children"></div>
                    </div>
                `
                this.$$(`#${td1Id}>.treeview-item-children`).append(td2Div)

                if (t1.children === null) continue
                for (const t2 of t1.children) {
                    // 加入第三级目录
                    const td3Id = `t2${this.utils.uuid()}`, td3Div = `
                        <div class="treeview-item treeview-item-opened" id="${td3Id}">
                            <div class="treeview-item-root">
                                <div class="treeview-item-content">
                                    <i class="icon iconfont" style="color: ${SensorStatus[t2.sensorStatus]};">
                                        ${SensorType[t2.sensorType]}
                                    </i>
                                    <div class="treeview-item-label">${t2.label}</div>
                                </div>
                            </div>
                        </div>
                    `
                    this.$$(`#${td2Id} .treeview-item-children`).append(td3Div);

                    this.$$(`#${td3Id}`).on("click", (event) =>{
                        const imgDiv = `
                            <div id="sensor-image">
                                <i class="icon iconfont" style="color: red; font-size: 30px;">
                                    ${SensorType[t2.sensorType]}
                                </i>
                            </div>
                        `;
                        this.$$(`#article`).append(imgDiv);

                        const top = this.$$("#map").offset().top, left = this.$$("#map").offset().left;
                        this.$$(`#sensor-image`).css('left', (window.event.clientX - left - 15) + 'px');
                        this.$$(`#sensor-image`).css('top', (window.event.clientY -top - 15) + 'px');

                        const self = this;
                        window.onmousemove = function() {
                            self.$$(`#sensor-image`).css('left', (window.event.clientX - left - 15) + 'px');
                            self.$$(`#sensor-image`).css('top', (window.event.clientY - top - 15) + 'px');
                        }

                        let isOnmouseup = true;
                        window.onmouseup = async function (e) {
                            if (isOnmouseup) {
                                self.$$(`#sensor-image`).remove();
                                const wx = window.event.clientX - left;
                                const wy = window.event.clientY - top;
                                const c = self.drawer.getCoordinateFromPixel([wx, wy]);
                                isOnmouseup = false;
                                self.app.dialog.confirm('确认添加传感器到此位置?', async () => {
                                    const sensor = {
                                        mineCode: config.mine_code,
                                        id: t2.id,
                                        label: t2.label,
                                        disasterType: t2.disasterType,
                                        disasterName: t2.disasterName,
                                        sensorType: t2.sensorType,
                                        sensorTypeName: t2.sensorTypeName,
                                        parentNodeId: t1.id,
                                        parentNodeLabel: t1.label,
                                        x: self.algo.denormalX(c[0]),
                                        y: self.algo.denormalY(c[1]),
                                        z: 0.0
                                    }
                                    const data = await self.api.updateTpCoord(sensor);
                                    if (data.code === 0) {
                                        self.toast('传感器坐标更新成功。')
                                        await self.refresh();
                                    }
                                })
                            }
                        }
                    })
                }
            }
        }
    }

    async sensorDetail(sensor, popupId, titleId, chartId) {
        const config = this.algo.getConfig();
        if (config === null) {
            this.toast('请优先选择煤矿。');
            return;
        }

        const params = {
            disasterType: sensor.disasterType,
            mineCode: config.mine_code,
            sensorCode: sensor.id,
            sensorType: sensor.sensorType,
            parentNodeId: sensor.parentNodeId
        };

        let data = await this.api.getSensorTips(params);
        if (data.data === null) {
            if (this.popupId !== '') {
                this.$$(`#${this.popupId}`).remove()
            }
            this.toast("传感器测点数据不存在...");
            return;
        }

        // 第一次出现时,显示属性
        this.$$(`#${titleId}`).empty();
        this.$$(`#${popupId}`).css('width', '480px');
        this.$$(`#${popupId}`).css('height', '200px');

        // 处理对话框移动
        const self = this, box = document.getElementById(popupId);
        box.onmousedown = function () {
            // 获取鼠标在div上按下的位置
            const e = window.event;
            let x1 = e.clientX, y1 = e.clientY;
            const left = parseInt(self.$$(`#${popupId}`).css('left').replace('px', ''));
            const top = parseInt(self.$$(`#${popupId}`).css('top').replace('px', ''));

            // 绑定移动事件
            document.onmousemove = function () {
                const e = window.event;
                let dx = e.clientX - x1, dy = e.clientY - y1;
                self.$$(`#${popupId}`).css('left', left + dx + 'px');
                self.$$(`#${popupId}`).css('top', top + dy + 'px');
            }
        }

        // 拖拽行为一定要记得解绑mousemove事件
        window.onmouseup = function () { document.onmousemove = null; }

        const div = `
            <div class="col-40 ol-popup-title-left">
                <i class="icon iconfont" style="font-size: 50px;">
                    ${SensorClass[sensor.disasterType]}
                </i>
                <h2>${sensor.sensorTypeName}</h2>
                <h4>${sensor.label}</h4>
            </div>
            <div class="col-60 ol-popup-title-right"></div>
        `;
        this.$$(`#${titleId}`).append(div);

        this.$$(`#${titleId} .ol-popup-title-right`).empty();
        for (let i = 0; i < data.data.metricRows.length; i++) {
            const item = data.data.metricRows[i];
            const str = `
                <h2 class='titleSpan'">
                    <label class='label1'>${item.metricName}</label>：
                    <label>${item.metricValue}</label>
                </h2>
            `;
            this.$$(`#${titleId} .ol-popup-title-right`).append(str);
            if (i === 5) break;
        }
        this.$$(`#${titleId} .ol-popup-title-right`).append(`<span>详细信息</span>`);

        // 点击“详细信息”时,显示chart图
        this.$$(`#${titleId} span`).on("click", async () => {
            const data = await this.api.getSensorDetails(params);
            if (data.data === null || data.data.x === null || data.data.y === null || data.data.x.length < 1) {
                this.toast("传感器测点数据不存在...");
                return;
            }

            // 设置详情div样式
            this.$$(`#${popupId}`).css('width', '600px');
            this.$$(`#${popupId}`).css('height', '300px');
            this.$$(`#${titleId}`).empty();
            const div = `
                <div class="col-30 ol-popup-title-left">
                    <i class="icon iconfont" style="font-size: 50px;">
                        ${SensorClass[sensor.disasterType]}
                    </i>
                    <h2>${sensor.sensorTypeName}</h2>
                    <h4>${sensor.label}</h4>
                </div>
                <div class="col-70 ol-popup-title-chart">
                    <div id="${chartId}" style="width: 380px; height: 250px;"></div>
                    <span>返回</span>
                </div>
            `;
            this.$$(`#${titleId}`).append(div);

            // 给Chart图设置数据
            const dom = document.getElementById(chartId);
            const chart = echarts.init(dom), series = [];
            for (const s of data.data.y) {
                const item = {
                    name: s.legend,
                    data: s.points,
                    type: 'line',
                    label: {
                        show: true,
                        position: 'top',
                        formatter: '{c}',
                        color: '#FFFFFF',
                        fontSize: '10px',
                        fontFamily: 'ArialMT'
                    },
                    lineStyle: { color: '#FFFFFF' }
                }
                series.push(item);
            }

            // 添加Chart图属性
            const option = {
                title: { text: '监测曲线', textStyle: { color: '#FFFFFF' } },
                grid: { top: '20%', left: '0%', right: '10%', bottom: '0%', containLabel: true },
                xAxis: { type: 'category', data: data.data.x },
                yAxis: { type: 'value' },
                "dataZoom": [{
                    "show": true,
                    "height": 5,
                    "xAxisIndex": [
                        0
                    ],
                    bottom: 0,
                    "start": 0,
                    "end": 100,
                    handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z',
                    handleSize: '110%',
                    handleStyle: {
                        color: "#d3dee5",

                    },
                    textStyle: {
                        color: "#fff"
                    },
                    borderColor: "#90979c"
                }, {
                    "type": "inside",
                    "show": true,
                    "height": 15,
                    "start": 1,
                    "end": 35
                }],
                series: series
            };
            option && chart.setOption(option);
            setTimeout(() => { chart.resize(); }, 200);

            // 点击"返回"回到属性页面
            this.$$(`#${titleId} .ol-popup-title-chart span`).on("click", async () => {
                await this.sensorDetail(sensor, popupId, titleId);
            })
        })
    }

    async sensorPin(sensor, i, id, x, y) {
        const closerId = `c${this.utils.uuid()}`;
        const titleId = `t${this.utils.uuid()}`;
        const chartId = `c${this.utils.uuid()}`;

        // 添加图钉框的div,并且确定在右边的位置
        const div = `
            <div id="${id}" class="ol-popup" style="position: fixed; border: 3px solid ${this.colors[i]}">
                <a href="#" id="${closerId}" class="ol-popup-closer"></a>
                <div class="row ol-popup-title" id="${titleId}"></div>
            </div>
        `;
        this.$$('article').append(div);
        this.$$(`#${id}`).css('left', `${x}px`);
        this.$$(`#${id}`).css('top', `${y}px`);

        // 在地图上添加彩色标记
        const feature = new Feature();
        const stroke = new Stroke({ width: 5, color: this.colors[i] });
        feature.setId(id);
        feature.setStyle(new Style({ stroke: stroke }));
        feature.setGeometry(new Circle([sensor.x, sensor.y], 3000));
        this.drawer.source(Type.Modify).addFeature(feature);

        // 关闭图钉框时: 需要分别删除图钉框、选中框和彩色标记
        this.$$(`#${closerId}`).on("click", async () => {
            this.$$(`#${id}`).remove();
            for (let i = 0; i < 8; i++) {
                if (this.pins[i].id === id) {
                    const pin = this.pins[i];
                    this.$$(`#${pin.popupId}`).remove();
                    pin.popupId = "";

                    // 在地图上删除彩色标记
                    const feature = this.drawer.source(Type.Modify).getFeatureById(id);
                    this.drawer.source(Type.Modify).removeFeature(feature);
                    break;
                }
            }
        });

        await this.sensorDetail(sensor, id, titleId, chartId);
    }

    async sensor(feature) {
        // 获取传感器的基础信息,并设置div的id
        if (this.popupId !== '') {
            this.$$(`#${this.popupId}`).remove()
        }

        const params = {
            id: feature.getId(),
            x: feature.get('x'), y: feature.get('y'),
            disasterType: feature.get('disasterType'),
            sensorType: feature.get('sensorType'),
            sensorTypeName: feature.get('sensorTypeName'),
            parentNodeId: feature.get('parentNodeId'),
            label: feature.get('label')
        };

        this.popupId = `p${this.utils.uuid()}`;
        const pinId = `d${this.utils.uuid()}`;
        const closerId = `c${this.utils.uuid()}`;
        const titleId = `t${this.utils.uuid()}`;
        const chartId = `c${this.utils.uuid()}`;
        const popupId = this.popupId

        // 添加选择对话框的div
        const div = `
            <div id="${popupId}" class="ol-popup">
                <span class="icon iconfont ol-popup-pin" id="${pinId}">&#xe7a5;</span>
                <a href="#" id="${closerId}" class="ol-popup-closer"></a>
                <div class="row ol-popup-title" id="${titleId}"></div>
            </div>
        `;
        this.$$('article').append(div);

        // 点击图钉按钮,固定到屏幕右边位置
        this.$$(`#${pinId}`).on("click", async () => {
            let isExite = false;

            // 给传感器看板找个位置
            for (let i = 0; i < 8; i++) {
                if (this.pins[i].popupId === "") {
                    const pin = this.pins[i];
                    pin.popupId = popupId;
                    await this.sensorPin(params, i, pin.id, this.pins[i].x, this.pins[i].y);
                    isExite = true;
                    break;
                }
            }

            // 找不到位置的情况下
            if (!isExite) {
                this.toast("固定位置最多只能放置8个.");
                return;
            }

            this.$$(`#${popupId}`).hide();
        });

        // 点击关闭按钮
        this.$$(`#${closerId}`).on("click", async () => {
            for (let i = 0; i < this.pins.length; i++) {
                if (this.pins[i].popupId === popupId) {
                    this.pins.splice(i, 1);
                }
            }
        });

        // 在地图上添加选择对话框
        const overlay = this.drawer.addOverlay(popupId, closerId);
        await this.sensorDetail(params, popupId, titleId, chartId);
        overlay.setPosition([params.x, params.y]);
    }

    socket() {
        const self = this;
        const config = self.algo.getConfig();
        if (config === null) return;

        const url = `${URL.WS_URL}/${config.mine_code}/qibinhai`;
        self.connect = new Socket(url);
        self.connect.create(async (data) => {
            if (data === "连接成功") {
                const req = {
                    action: "gis2d/getDisasterTpTree",
                    toSid: "qibinhai",
                    reqBody: {
                        mineCode: config.mine_code,
                        requestId: "string"
                    }
                }
                self.connect.send(req);
                return;
            }

            const sensor = JSON.parse(data);
            self.utils.setLocalStorage("sensor", sensor.data);
            await self.refresh(sensor.data);
        });

        self.emitter.on("socket-close", () => {
            if (self.connect) {
                self.connect.close();
                self.connect = null;
                console.log("Socket closed!");
            }
        });
    }

    template() { }

    control() {
        // 从选择器接收发来的消息
        this.emitter.on("sensor-selected", async () => {
            const feature = this.emitter.params[0];
            await this.sensor(feature);
        });

        this.$$("#sensor").on("click", async () => {
            this.$$("#pannel").show();
            this.$$("#pannel span").text('传感器');
            await this.tree();
        });

        const self = this;
        self.emitter.on("sensor-refresh", async () => {
            await self.refresh();
        });
    }
}